#include "vector.h"
#include <cmath>

Vector::Vector()
{
    elements[3] = 0;
}

Vector::Vector(double x, double y, double z)
{
    elements[0] = x;
    elements[1] = y;
    elements[2] = z;
    elements[3] = 0;
}

Vector::Vector(const Vector &v)
{
    this->copy(v);
    (*this)(3) = 0;
}

Vector::~Vector()
{
}

Vector& Vector::operator=(const Vector &v)
{
    if( this != &v ) {
        this->copy(v);
        (*this)(3) = 0;
    }

    return  *this;
}

double Vector::norm() const
{
    double temp = (*this)(0) * (*this)(0)
               + (*this)(1) * (*this)(1)
               + (*this)(2) * (*this)(2);

    return sqrt(temp);
}

double Vector::sproject(const Vector &v) const {
    return ((*this)*v) / v.norm();
}

Vector Vector::project(const Vector &v)  const {
    double temp = v.norm();
    temp = (*this)*v /(temp*temp);

    return temp * v;
}

Vector& Vector::normalize()
{
    double n = this->norm();

    (*this)(0) = (*this)(0) / n;
    (*this)(1) = (*this)(1) / n;
    (*this)(2) = (*this)(2) / n;

    return *this;
}



void Vector::copy(const Vector &v)
{
    (*this)(0) = v(0);
    (*this)(1) = v(1);
    (*this)(2) = v(2);
}

Vector operator+(const Vector &left, const Vector &right)
{
    Vector c;
    for(int i = 0 ; i < 4 ; i++)
        c(i) = left(i) + right(i);

    return c;
}

Vector operator-(const Vector &left, const Vector &right)
{
    Vector c;
    for(int i = 0 ; i < 4 ; i++)
        c(i) = left(i) - right(i);

    return c;
}

double operator*(const Vector &left, const Vector &right)
{
    double dotprod = 0;
    for(int i = 0 ; i < 4 ; i++)
        dotprod += left(i) * right(i);

    return dotprod;
}

Vector operator*(double s, const Vector& v) {
    return Vector(s*v(0), s*v(1), s*v(2));
}

Vector operator*(const Vector& v, double s) {
    return s*v;
}

Vector operator/(const Vector& v, double s) {
    return Vector(v(0)/s, v(1)/s, v(2)/s);
}

Vector operator-(const Vector& v) {
    return Vector(-v(0), -v(1), -v(2));
}

Vector vecprod(const Vector &left, const Vector &right)
{
    Vector c;

    c(0) = left(1)*right(2) - right(1)*left(2);
    c(1) = left(2)*right(0) - right(2)*left(0);
    c(2) = left(0)*right(1) - right(0)*left(1);
    return c;
}

double cossine(const Vector &left, const Vector &right)
{
    return (left.norm()*right.norm()) / (left*right);
}

double angle(const Vector &left, const Vector &right)
{
    return acos(cossine(left, right));
}


